<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
	</head>
	<body>
		<script>
			// 类相当于实例的原型，所有在类中定义的方法，都会被实例继承
			// 加上static关键字，就表示该方法不会被实例继承，而是直接通过类来调用，这就称为“静态方法”。
			// 如果静态方法包含this关键字，这个this指的是类，而不是实例
      // 静态方法可以与非静态方法重名。
      // =============================================子类父类
      // 父类的静态方法，可以被子类继承。子类继承父类时，new.target会返回子类
      // super(x, y); // 调用父类的constructor(x, y)，siper()表示父类的构造函数，用来新建父类的this对象
			// 静态方法也是可以从super对象上调用的
			// =========================================
			// Class 内部只有静态方法，没有静态属性
			// 静态属性的写法
			// class Foo {}
			// Foo.prop = 1
			// Foo.prop // 1
			// // 老写法------------------
			// class Foo {
			// 	// ...
			// }
			// Foo.prop = 1
			// // 新写法--------------
			// class Foo {
			// 	static prop = 1
      // }
      // ========================
      // class私有属性
      // #count = 0
      // https://es6.ruanyifeng.com/#docs/class#%E7%A7%81%E6%9C%89%E5%B1%9E%E6%80%A7%E7%9A%84%E6%8F%90%E6%A1%88

			class Logger {
				// new class时自动调用
				// 一个类必须要constructor属性，否则自动添加
				// constructor 默认返回实例对象，即this
				constructor(x) {
					this.x = x
				}

				// 静态方法，不会被继承，只能通过类来调用，不能通过实例来调用
				static classMethod() {
					return 'hello'
				}

				printName(name = 'there') {
					this.print(`Hello ${name}`)
				}

				print(text) {
					console.log(text)
				}
			}

			let logger = new Logger(123)

			const proxy = new Proxy(logger, {
				get(logger, x) {
					console.log('get==>', logger[x])
					return logger[x]
				},
				set(logger, x, value) {
					console.log('set==>', value)
					logger[x] = value
				}
			})
			console.log(proxy.x)
			proxy.x = 55
			console.log(proxy.x)

			function selfish(target) {
				// WeakMap的键值只能是对象的引用，且是弱引用
				const cache = new WeakMap()

				const proxy = new Proxy(target, {
					get(target, key) {
						const value = Reflect.get(target, key)
						console.log('value==>', value)

						// 所有不是函数的均返回自身
						if (typeof value !== 'function') {
							return value
						}

						// 所有是函数的属性通过WeakMap，改变this指向
						if (!cache.has(value)) {
							cache.set(value, value.bind(target))
						}

						// 最终返回修正过this指向的函数
						return cache.get(value)
					}
				})
				return proxy
			}

			selfish(new Logger())

			// =============================================

			class Foo {
				constructor() {
					console.log('=====================', 'Foo')
				}
				static classMethod() {
					return 'hello'
				}
			}

			class Bar extends Foo {
				constructor() {
					console.log('super==>', super())
				}
				static classMethod() {
					return super.classMethod() + ', too'
				}
			}

			console.log('new Bar()=>>>>', new Bar())
			console.log(Bar.classMethod())
		</script>
	</body>
</html>
